'''
Created on Sep 7, 2012

@author: petrina
'''
from link_indicator import Link_indicator
import logging
import math 

class Correlation_coefficient(Link_indicator):
    '''
    Calculates the correlation coefficient for every time interval (using aggregated fcd-data).
    
    Formula for calculating the indicator: 
        c_i = a_i/sqrt(b_i * g_i)
        a_i = n * sum(x_i_d*y_i_d) - sum(x_i_d)*sum(y_i_d) 
        b_i = n * sum(x_i_d^2 - sum(x_i_d)^2)
        g_i = n * sum(y_i_d^2 - sum(y_i_d)^2)
            where
              - c_i  ... correlation coefficient for the time interval i
              - x_i_d  ... analyzed data on the day d and interval i
              - y_i_d  ... reference data on the day d and interval i
              - n ... number of days
    
    unit: index value
    '''


    def __init__(self, link):
        '''        
        @param link: Link-object (containing valid records and reference) 
        '''
        
        Link_indicator.__init__(self, link)
        self._name = 'Correlation Coefficient'
        self._mr_name =  'corr_coef'
        self._unit = 'index'
        #self.unit.__doc__ = 'index value'
        

        self._create_title(link.id, link.direction)
        
        logging.debug("Correlation_coefficient: created new Correlation_coefficient")
        
    #----------------------public methods of the class-------------------------

    def calculate(self):
        '''
        Calculates the correlation coefficient with the fleet-data and the reference data.
        
        @return: list of Result_values for the correlation coefficient for every time interval
        '''
        
        logging.info("Correlation_coefficient: staring to calculate the correlation coefficient")
         
        # list for the resulting values       
        values = []
        
        self._xvalues = []
        self._yvalues = []
        
        # for all intervals
        for i in range(self._intervals):
            ref_data = self._link.reference[i]
            rec_data = self._link.records[i]
            
            value = None
            if len(ref_data) > 0 and len(rec_data) > 0:            
                
                min_time = min(rec_data.begintime, ref_data.begintime)
                max_time = max(rec_data.endtime, ref_data.endtime)
                
                x = rec_data.create_value_list(min_time, max_time, attribute = 'speed') 
                y = ref_data.create_value_list(min_time, max_time, attribute = 'speed') 
                
                self._xvalues += y
                self._yvalues += x
                
                # sum of values on a day     
                sum_x = 0  
                sum_y = 0
                sum_xy = 0
                sum_xx = 0
                sum_yy =0  
                
                # number of values
                n = 0
                
                # for every day
                for j in range(len(y)):           
                    if y[j] is not None and x[j] is not None:
                        sum_x += x[j]
                        sum_y += y[j]
                        sum_xy += x[j] * y[j]
                        sum_xx += x[j] * x[j]
                        sum_yy += y[j] * y[j]
                        n += 1
                
                # no division by zero    
                if n > 0:
                    # formula for correlation coefficient
                    denominator = math.sqrt((n * sum_xx - sum_x * sum_x)*(n * sum_yy - sum_y * sum_y))
                    if denominator != 0:
                        value = (n * sum_xy - sum_x * sum_y)/denominator
                    else:
                        logging.info("Correlation_coefficient: dominator 0 - value remains None")
                
            values.append(value)
             
        self._values = values

        logging.debug("Correlation_coefficient: finished calculating the correlation coefficient")

        return self._values
    
    
    def plot(self, plotobject):
        # plot indicator
        Link_indicator.plot(self, plotobject)
        
        # create the correlation-plot
        plotobject.create_new_plot(title = "Correlation-plot", xlabel='observed [km/h]', ylabel='estimated [km/h]')
        for i in range(len(self._xvalues)):
            plotobject.plot(self._xvalues[i], self._yvalues[i])     
        plotobject.save_plot2png("corr_plot_"+self._exp_title, 'png') 
        
    
